九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、Laravel 5.7
が公開されたということで、ここのところLaravel関連の記事が続きましたが、今回はLaravelと同様に、生産性が高いJSフレームワーク「Vue」の話題をお届けします。
ちなみにVueは、wordpressが権利問題の関係からReact.jsの利用をやめようとしたとき白羽の矢が立ったJSフレームワークで、学習コストがより少なく済む(つまり、誰でも保守しやすい)ので私はこちらを進んで利用するようにしています。
では、そんなVue.jsを使って今回はインプットで選択された画像を瞬時にプレビューする方法を紹介します!
目次
やりたいこと
- <input type=”file”> で画像を選択
- 自動的に選択ボックスの下にプレビューを表示する
もちろん、プレビュー画像がなくても問題はないでしょうが、視覚的に何を選んだかが分かればユーザーとしては安心してデータ送信できますので、一番の目的はユーザビリティの向上ということになります。
表示部分をつくる
bootstrapを読み込む
見栄えを良くしたいので、<head>〜</head>
内でbootstrap(CSSフレームワーク)をcdn経由で読み込みます。
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
画像の選択部分を作成する
<div class="card" style="width: 20rem;margin:10px;"> <div class="card-body"> <h4 class="card-title">画像を選んでください。</h4> <input type="file" accept="image/*"> </div> </div>
いろいろと装飾してはいますが、ここで必要となるのは<input type="file">
部分だけです。ただ、画像だけ選択できるように、accept="image/*"
を追加しておきましょう。
Vue部分をつくる
基本コードを作る
では、ここからVueを使ってJavaScript部分を作成していきます。
<body> <div id="app"> (省略) </div> </body>
まずは、Vueが利用できるようにid
を必要部分に作成。
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script> <script> new Vue({ el: '#app', data: { imageData: '' } }); </script>
そして、Vue.jsをcdn経由で読み込んだら基本コードをつくり、変数imageData
を登録。ここに選択された画像データを格納することになります。
イベントを登録する
では、次に<input type="file">
に画像が選択されたら起動するchangeイベント
を登録しましょう。
<input type="file" accept="image/*" @change="onFileChange($event)">
ここで重要なのは、$event
です。こうすることで、イベント内容をonFileChange()
へ送信することができるんですね。
では、メソッド部分です。
methods: { onFileChange(e) { // ここで画像を読み込む } }
先ほど指定した$event
がe
として使えるように変数を追加します。
画像データを読み込む
では、onFileChange()内で画像データを読み込むコードをつくります。
onFileChange(e) { const files = e.target.files; if(files.length > 0) { const file = files[0]; const reader = new FileReader(); reader.onload = (e) => { this.imageData = e.target.result; }; reader.readAsDataURL(file); } },
やっていることは、
const files = e.target.files; if(files.length > 0) { // 省略 }
の部分で、ファイルが本当に選択されたかをチェックし、
const file = files[0]; const reader = new FileReader(); reader.onload = (e) => { this.imageData = e.target.result; }; reader.readAsDataURL(file);
もしファイルが存在していたら、FileReader()を使って画像を読み込み、データをimageData
に格納するようにしています。
ちなみにES6で書いているのでthis.imageData
で問題ありませんが、IE対応したい場合は以下のようにself
を使って画像データを格納してください。
var self = this; var file = files[0]; var reader = new FileReader(); reader.onload = function(e) { self.imageData = e.target.result; }; reader.readAsDataURL(file);
(マイクロソフトさん、そろそろIEは廃止にしましょう・・・ ^^;)
画像の表示プレビューをつくる
では、最後の項目です。<img>
タグを追加して、もしimageData
に画像データがある場合だけ表示するようにしてみましょう。
<img :src="imageData" v-if="imageData">
やっぱりVueだとコードがシンプルですね!
実際にやってみる
では、実際にプレビューされるかみてみましょう。
<input type="file">
をクリックして、Vueのロゴ画像を選択すると・・・・・・
うまく画像を表示することができました!
もちろんこの状態から違う画像を選択すると、以下のように内容が自動で切り替わります。
おまけ
選択をリセットするボタンをつける
せっかくなので、選択された画像をリセットする機能もつけましょう。
まず、<input type="file">
へVueからアクセスできるようref
を追加します。
<input type="file" ref="file" accept="image/*" @change="onFileChange($event)">
これでthis.$refs.file
として要素にアクセスできるようになりました。
<button class="btn btn-danger" v-if="imageData" @click="resetFile()">リセット</button>
そして、リセットボタンを作成。画像があるときだけボタンを表示するようにして、クリックしたらresetFile()
を実行するようにします。
resetFile() { const input = this.$refs.file; input.type = 'text'; input.type = 'file'; this.imageData = ''; }
resetFile()
の中では、インプット要素のtypeを一旦text
へ変更して元に戻すことでリセットを実装しています。また、imageData
も元に戻すのを忘れないようにしましょう。
これで、画像を選択したらリセットボタンが表示され、
リセットボタンをクリックすると、初期状態にもどるようになりました。
お疲れ様でした!
実際のコード(ダウンロード)
実際のソースコードをダウンロードできます。
cdnでCSS、JSを読み込んでいるので、展開してブラウザで開くだけでサンプルを試すことができますよ!
おわりに
ということで今回はVueJSを使って選択画像をリアルタイムにプレビュー表示する方法を紹介しました。
やはりVueを使えばコードをシンプルに書けますし、描画スピードも高速(最近はjQueryでも十分高速ですが)なので、嬉しい限りです。
ちなみに今回からですが、実験的にソースコードをダウンロードできるようにしてみました。
というのも、このブログはプログラム関連の話題ということで、訪問ユーザーさんの大多数にはPCブラウザを使って閲覧していただいています。そこで、ファイルダウンロードがあると嬉しいかな?と考えました。
もしあまり使われなかったら、ダウンロード機能はなくすかもしれませんが少しの間はテスト期間ということで設置します。もし良かったらぜひ活用してくださいね。
ではでは〜!